package com.qiangesoft.multithread.service.impl;

import com.qiangesoft.multithread.entity.MallOrder;
import com.qiangesoft.multithread.service.IMallCustomerService;
import com.qiangesoft.multithread.service.IMallGoodsService;
import com.qiangesoft.multithread.service.IMallOrderService;
import com.qiangesoft.multithread.service.IMallShopService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.concurrent.*;

/**
 * <p>
 * 订单信息 服务实现类
 * </p>
 *
 * @author qiangesoft
 * @since 2024-05-06
 */
@Slf4j
@Service
public class MallOrderServiceImpl implements IMallOrderService {

    @Autowired
    private IMallGoodsService mallGoodsService;
    @Autowired
    private IMallCustomerService mallCustomerService;
    @Autowired
    private IMallShopService mallShopService;

    private static int coreSize = Runtime.getRuntime().availableProcessors();

    private final ExecutorService executorService = new ThreadPoolExecutor(coreSize,
            coreSize * 5,
            5L,
            TimeUnit.MINUTES,
            // 最大容量为1的队列
            new SynchronousQueue<>(),
            // 拒绝策略，降级到主线程执行
            new ThreadPoolExecutor.CallerRunsPolicy());

    @Override
    public MallOrder getById(Long id) {
        long startTime = System.currentTimeMillis();

        MallOrder mallOrder = new MallOrder();
        mallOrder.setId(1L);
        mallOrder.setShopId(3L);
        mallOrder.setCustomerId(78L);
        mallOrder.setGoodsId(664L);
        mallOrder.setOrderTime(LocalDateTime.now());
        mallOrder.setOrderStatus(1);
        mallOrder.setTotalAmount(new BigDecimal("129.8"));

        // 商品
        Future<Long> goodsFuture = executorService.submit(() -> mallGoodsService.getById(mallOrder.getGoodsId()));

        // 顾客
        Future<Long> customerFuture = executorService.submit(() -> mallCustomerService.getById(mallOrder.getCustomerId()));

        // 店铺
        Future<Long> shopFuture = executorService.submit(() -> mallShopService.getById(mallOrder.getShopId()));

        try {
            Thread.sleep(150);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        try {
            log.info("商品：" + goodsFuture.get());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        try {
            log.info("顾客：" + customerFuture.get());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        try {
            log.info("店铺：" + shopFuture.get());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        long endTime = System.currentTimeMillis();
        log.info("耗时：" + (endTime - startTime));
        return mallOrder;
    }

    @Override
    public MallOrder getById1(Long id) {
        long startTime = System.currentTimeMillis();

        MallOrder mallOrder = new MallOrder();
        mallOrder.setId(1L);
        mallOrder.setShopId(3L);
        mallOrder.setCustomerId(78L);
        mallOrder.setGoodsId(664L);
        mallOrder.setOrderTime(LocalDateTime.now());
        mallOrder.setOrderStatus(1);
        mallOrder.setTotalAmount(new BigDecimal("129.8"));

        // 商品
        Long goodsId = mallGoodsService.getById(mallOrder.getGoodsId());
        log.info("商品：" + goodsId);

        // 顾客
        Long customerId = mallCustomerService.getById(mallOrder.getCustomerId());
        log.info("顾客：" + customerId);


        // 店铺
        Long shopId = mallShopService.getById(mallOrder.getShopId());
        log.info("店铺：" + shopId);


        try {
            Thread.sleep(150);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        long endTime = System.currentTimeMillis();
        log.info("耗时：" + (endTime - startTime));
        return mallOrder;
    }
}
